\CUSProvideExplLibrary{analysis}{\cus@d@te}{\cus@versi@n}{analysis token(s)}

\bool_new:N \l_cus_analysis_interactive_bool 
\int_new:N \l__cus_analysis_depth_int 
\int_new:N \g__cus_analysis_currdepth_int 
\tl_new:N \l__cus_analysis_cstype_tl 
\tl_new:N \l__cus_analysis_string_tl
\tl_new:N \l__cus_analysis_meaning_tl
\tl_new:N \l__cus_analysis_catcode_tl
\tl_new:N \l__cus_analysis_charcode_tl
\tl_const:Nn \c_cus_analysis_sep_tl { ;~ }
\cs_new:Npn \cus_analysis_sep: { \exp_not:N \c_cus_analysis_sep_tl }
\cs_new:Npn \__cus_exp_args:ne #1#2 { \use:e { \exp_not:n {#1} {#2} } }
\cs_new:Npn \__cus_exp_last_unbraced:ne #1#2 { \use:e { \exp_not:n {#1} #2 } }
\cs_new:Npn \__cus_if_cs_exist:NTF #1
  {
    \if_cs_exist:N #1 
      \exp_after:wN \use_i:nn
    \else:
      \exp_after:wN \use_ii:nn
    \fi:
  }

\cs_new_eq:NN \__cus_if_newoptcommand:NTF \@if@newcommand 
\cs_new_eq:NN \__cus_if_robustcommand:NTF \@if@DeclareRobustCommand
\cs_new_eq:NN \__cus_if_xparsecommand:NTF \__kernel_cmd_if_xparse:NTF
\cs_new_eq:NN \__cus_command_act:NNNn \robust@command@act% act list, cmd, fallback, args
% cmd, normal, expandable, env, env end, false 
\cs_new_eq:NN \__cus_cmd_type_cases:NnnnnF \__cmd_cmd_type_cases:NnnnnF 
\cs_new_protected:Npn \__cus_if_quark:NTF #1
  { \exp_args:No \tl_if_eq:nnTF {#1} {#1} }
\cs_new_protected:Npn \__cus_if_seq:NTF #1
  {
    \tl_if_eq:NNTF #1 \c_empty_seq
      { \use_i:nn }
      {
        \exp_after:wN \__cus_if_seq_aux:w #1 \s__seq \__seq_item:n \s__cus_nil \s__cus_stop
      }
  }
\cs_new:Npn \__cus_if_seq_aux:w #1 \s__seq \__seq_item:n #2 #3 \s__cus_stop
  { \tl_if_empty:nTF {#3} { \use_ii:nn } { \use_i:nn } }
\cs_new_protected:Npn \__cus_if_prop:NTF #1
  {
    \tl_if_eq:NNTF #1 \c_empty_prop
      { \use_i:nn }
      {
        \exp_after:wN \__cus_if_prop_aux:w #1 
          \s__prop \__prop_pair:wn { } \s__prop { } \s__cus_stop
      }
  }
\cs_new:Npn \__cus_if_prop_aux:w #1 \s__prop \__prop_pair:wn #2 \s__prop #3 #4 \s__cus_stop
  { \tl_if_empty:nTF {#4} { \use_ii:nn } { \use_i:nn } }
\cs_new:Npn \__cus_if_fp:NTF #1 
  {
    \exp_after:wN \__cus_if_fp_aux:w #1 \s__fp \__fp_chk:w {}{}{} ; \s__cus_stop
  }
\cs_new:Npn \__cus_if_fp_aux:w #1 \s__fp \__fp_chk:w #2; #3 \s__cus_stop
  { \tl_if_empty:nTF {#3} { \use_ii:nn } { \use_i:nn } }

% tl, fp, prop, quark, seq, fallback, args list 
\cs_new_protected:Npn \cus_tl_analysis_data_type_act:NNNNNNn #1#2#3#4#5#6
  {
    \tl_set:Nn \l__cus_analysis_action_data_type_tl 
      { { 
          \__cus_if_fp:NTF    #2
          \__cus_if_prop:NTF  #3
          \__cus_if_quark:NTF #4
          \__cus_if_seq:NTF   #5
      } }
    \__cus_command_act:NNNn \l__cus_analysis_action_data_type_tl #1 #6
  }
% tl, newcommand, DeclareRobustCommand, document, fallback, args list
\cs_new_protected:Npn \cus_tl_analysis_cmd_act_short:NNNNNn #1#2#3#4#5
  {
    \tl_set:Nn \l__cus_analysis_action_list_short_tl
      { {
          \__cus_if_newoptcommand:NTF #2
          \__cus_if_robustcommand:NTF #3
          \__cus_if_xparsecommand:NTF #4
      } }
    \__cus_command_act:NNNn \l__cus_analysis_action_list_short_tl #1 #5
  }
\cs_new_eq:NN \cus_tl_analysis_cmd_act:NNNNNn \cus_tl_analysis_cmd_act_short:NNNNNn
% tl, newcommand, DeclareRobustCommand, document normal, expandable, env, env end, fallback , args list
\cs_new_protected:Npn \cus_tl_analysis_cmd_act_full:NNNNNNNNn #1#2#3#4#5#6#7#8
  {
    \tl_set:Nn \l__cus_analysis_action_list_full_tl
      { {
          \__cus_if_newoptcommand:NTF #2
          \__cus_if_robustcommand:NTF #3
      } }
    \cs_set:Npn \__cus_analysis_fallback:w 
      { \__cus_cmd_type_cases:NnnnnF #1 {#4} {#5} {#6} {#7} {#8} }
    \__cus_command_act:NNNn \l__cus_analysis_action_list_full_tl #1
      \__cus_analysis_fallback:w 
  }

\cs_new_protected:Npn \__cus_macro_if_argumentless:NTF #1 
  { \tl_if_empty:eTF { \cs_argument_spec:N #1 } }


\cs_new_protected:Npn \cus_analysis_tl_show:n #1
  {
    \group_begin:
    \int_set:Nn \tex_escapechar:D { `\\ }
    \int_gzero:N \g__cus_analysis_currdepth_int
    \__cus_analysis_tl:nnn { \iow_term:x } { \iow_newline: } {#1}
    \msg_show:nn { cus } { analysis-tl }
    \group_end:
  }
\cs_new_protected:Npn \cus_analysis_tl_show:N { \exp_args:No \cus_analysis_tl_show:n }
\cs_new_protected:Npn \cus_analysis_tl_log:n #1
  {
    \group_begin:
    \int_set:Nn \tex_escapechar:D { `\\ }
    \int_gzero:N \g__cus_analysis_currdepth_int
    \__cus_analysis_tl:nnn { \iow_log:x } { \iow_newline: } {#1}
    \group_end:
  }
\cs_new_protected:Npn \cus_analysis_tl_log:N { \exp_args:No \cus_analysis_tl_log:n }
\msg_new:nnn { cus } { analysis-tl } { (End~of~tl). }
\cs_new_protected:Npn \__cus_analysis_tl:nnn #1#2#3 % function, newline, tl 
  {
    \tl_analysis_map_inline:nn {#3}
      { 
        \tl_clear:N \l__cus_analysis_cstype_tl
        \tl_set:Nx \l__cus_analysis_catcode_tl { \int_value:w "##3 }
        \tl_set:Nx \l__cus_analysis_charcode_tl { ##2 }
        \tl_set:Nx \l__cus_analysis_string_tl { \exp_after:wN \token_to_str:N ##1 }
        \tl_set:Nx \l__cus_analysis_meaning_tl { \exp_after:wN \token_to_meaning:N ##1 }
        \use:c { __cus_analysis_ \l__cus_analysis_catcode_tl :nnn } {#1} {#2} {##1}
      }
  }
\cs_new_protected:Npn \__cus_analysis_new:nn #1 
  { \cs_new_protected:cpn { __cus_analysis_ #1 :nnn } ##1##2##3 }
\cs_new_protected:Npn \__cus_analysis_new_eq:nn #1 #2
  { \cs_new_eq:cc { __cus_analysis_ #1 :nnn } { __cus_analysis_ #2 :nnn } }
\__cus_analysis_new:nn { 0 } % control sequence
  { 
    \tl_replace_all:Nnn \l__cus_analysis_string_tl { ~ } { ␣ }
    \exp_after:wN \__cus_analysis_control_sequence:Nnn #3 {#1} {#2}
  }
\cs_new:Npn \__cus_analysis_control_sequence:Nnn #1#2#3
  {
    \str_if_eq:eeTF { \token_to_str:N #1 } { \exp_not:n {#1} }
      {
        \tl_set:Nx \l__cus_analysis_result_tl 
          { control~symbol~ \l__cus_analysis_string_tl }
      }
      {
        \tl_set:Nx \l__cus_analysis_result_tl
          { control~word~ \l__cus_analysis_string_tl }
      }
    \cus_token_if_implicit_char:NTF #1
      { 
        \tl_put_right:Nn \l__cus_analysis_result_tl 
          { 
            \cus_analysis_sep: 
            implicit~character 
            \cus_analysis_sep: 
            \l__cus_analysis_meaning_tl 
          }
      }
      {
        \__cus_if_cs_exist:NTF #1
          {
            \token_if_macro:NTF #1
              {
                \__cus_macro_if_argumentless:NTF #1
                  { \__cus_analysis_control_sequence_argumentless:Nnn #1 {#2} {#3} }
                  { \__cus_analysis_control_sequence_argument:Nnn #1 {#2} {#3} }
              }
              {
                \token_if_primitive:NT #1 
                  { 
                    \tl_put_right:Nn \l__cus_analysis_result_tl 
                      { \cus_analysis_sep: primitive } 
                  }
                \tl_put_right:Nn \l__cus_analysis_result_tl 
                  { \cus_analysis_sep: \l__cus_analysis_meaning_tl }
              }
          }
          {
            \tl_put_right:Nn \l__cus_analysis_result_tl 
              { \cus_analysis_sep: undefined }
          }
      }
    \__cus_exp_args:ne {#2} { \__cus_analysis_indent: \l__cus_analysis_result_tl }
    \prg_break_point:
  }
\cs_new:Npn \__cus_analysis_control_sequence_argument:Nnn #1#2#3 
  {
    \tl_put_right:Nn \l__cus_analysis_result_tl { \cus_analysis_sep: }
    \tl_put_right:Nx \l__cus_analysis_result_tl 
      { \__cus_analysis_macro_prefix:N #1 }
    \__cus_analysis_interactive:Nnn #1
      { Finding~macro~(with~argument(s)) }
      {
        { meaning } { \tl_show:o \l__cus_analysis_meaning_tl }
        { prefix } { \tl_show:e { \cs_prefix_spec:N #1 } }
        { argument } { \tl_show:e { \cs_argument_spec:N #1 } }
        { replacement } { \tl_show:e { \cs_replacement_spec:N #1 } }
      }
  }
\cs_new:Npn \__cus_analysis_macro_prefix:N #1
  { \exp_after:wN \__cus_analysis_macro_prefix:w \token_to_meaning:N #1 \s__cus_stop }
\cs_set:Npn \__cus_tmp:w #1
  {
    \cs_new:Npn \__cus_analysis_macro_prefix:w ##1 #1 ##2 \s__cus_stop { ##1 macro }
  }
\exp_args:No \__cus_tmp:w { \tl_to_str:n { macro: } }
\cs_new:Npn \__cus_analysis_control_sequence_argumentless:Nnn #1#2#3 
  {
    \tl_put_right:Nn \l__cus_analysis_result_tl { \cus_analysis_sep: }
    \cus_tl_analysis_cmd_act_full:NNNNNNNNn #1
      \__cus_analysis_control_sequence_newoptcommand:Nnn 
      \__cus_analysis_control_sequence_robustcommand:Nnn 
      \__cus_analysis_control_sequence_xparsecommand:Nnn 
      \__cus_analysis_control_sequence_expandablecommand:Nnn 
      \__cus_analysis_control_sequence_envcommand:Nnn 
      \__cus_analysis_control_sequence_envenvcommand:Nnn 
      \__cus_analysis_control_sequence_cmdelse:Nnn { #1 {#2} {#3} }
  }
\cs_new:Npn \__cus_analysis_control_sequence_newoptcommand:Nnn #1#2#3
  {
    \__cus_analysis_cstype_and_push:n { newcommand~with~option }
    \__cus_analysis_command_interactive:N #1
  }
\cs_new:Npn \__cus_analysis_control_sequence_robustcommand:Nnn #1#2#3
  {
    \__cus_analysis_cstype_and_push:n { robust~command }
    \__cus_analysis_command_interactive:N #1
  }
\cs_new:Npn \__cus_analysis_control_sequence_xparsecommand:Nnn #1#2#3
  {
    \__cus_analysis_cstype_and_push:n { document~command }
    \__cus_analysis_command_interactive:N #1
  }
\cs_new:Npn \__cus_analysis_control_sequence_expandablecommand:Nnn #1#2#3
  {
    \__cus_analysis_cstype_and_push:n { document~expandable~command }
    \__cus_analysis_command_interactive:N #1
  }
\cs_new:Npn \__cus_analysis_control_sequence_envcommand:Nnn #1#2#3
  {
    \__cus_analysis_cstype_and_push:n { document~environment }
    \__cus_analysis_command_interactive:N #1
  }
\cs_new:Npn \__cus_analysis_control_sequence_envenvcommand:Nnn #1#2#3
  {
    \__cus_analysis_cstype_and_push:n { document~end~environment }
    \__cus_analysis_command_interactive:N #1
  }
\cs_new:Npn \__cus_analysis_command_interactive:N #1
  {
    \__cus_analysis_interactive:Nnn #1
      {
        Finding~
        \tl_if_empty:NTF \l__cus_analysis_cstype_tl
          { macro } { \l__cus_analysis_cstype_tl }
      }
      {
        { show } { \ShowCommand #1 }
      }
  }
\cs_new:Npn \__cus_analysis_cstype_and_push:n #1
  {
    \tl_set:Nn \l__cus_analysis_cstype_tl {#1}
    \tl_put_right:Nn \l__cus_analysis_result_tl {#1}
  }
\cs_new_protected:Npn \__cus_analysis_execute_term:N #1
  {
    \ior_get_term:nN { execute } \l__cus_analysis_input_tl
    \__cus_analysis_replace:Nnn\l__cus_analysis_input_tl 
      { $(token) } { #1 } % $
    \__cus_analysis_replace:Nno \l__cus_analysis_input_tl
      { $(charcode) } { \l__cus_analysis_charcode_tl } % $
    \__cus_analysis_replace:Nno \l__cus_analysis_input_tl
      { $(catcode) } { \l__cus_analysis_catcode_tl } % $
    \__cus_analysis_replace:Nno \l__cus_analysis_input_tl 
      { $(meaning) } { \l__cus_analysis_meaning_tl } % $
    \__cus_analysis_replace:Nnn \l__cus_analysis_input_tl 
      { $(nonstop) } { \bool_set_false:N \l_cus_analysis_interactive_bool } % $
    \__cus_analysis_replace:Nnn \l__cus_analysis_input_tl
      { $(next) } { \__cus_analysis_execute_term:N #1 } % $
    \tl_use:N \l__cus_analysis_input_tl
  }
\cs_new_protected:Npn \__cus_analysis_replace:Nnn #1#2#3
  { \tl_set:Nx #1 { \exp_args:No \etl_replace_all_deep:nnn #1 {#2} {#3} } }
\cs_generate_variant:Nn \__cus_analysis_replace:Nnn { Nno }
\cs_new:Npn \__cus_analysis_control_sequence_cmdelse:Nnn #1#2#3
  {
    \cus_tl_analysis_data_type_act:NNNNNNn #1
      \__cus_analysis_control_sequence_fp:Nnn 
      \__cus_analysis_control_sequence_prop:Nnn 
      \__cus_analysis_control_sequence_quark:Nnn 
      \__cus_analysis_control_sequence_seq:Nnn 
      \__cus_analysis_control_sequence_else:Nnn { #1 {#2} {#3} }
  }
\cs_new:Npn \__cus_analysis_control_sequence_fp:Nnn #1#2#3
  {
    \tl_put_right:Nn \l__cus_analysis_result_tl
      { 
        float~number:~ 
        \token_case_meaning:NnF #1
          {
            \c_e_fp    { e }
            \c_pi_fp   { Pi }
            \c_inf_fp  { Inf }
            \c_nan_fp  { NaN }
          }
          { \fp_to_decimal:N #1 }
      }
  }
\cs_new:Npn \__cus_analysis_control_sequence_prop:Nnn #1#2#3
  {
    \__cus_analysis_cstype_and_push:n { prop }
    \__cus_analysis_data_type_interactive:NN #1 \prop_show:N
  }
\cs_new:Npn \__cus_analysis_control_sequence_quark:Nnn #1#2#3
  { 
    \__cus_analysis_cstype_and_push:n { quark }
  }
\cs_new:Npn \__cus_analysis_control_sequence_seq:Nnn #1#2#3
  {
    \__cus_analysis_cstype_and_push:n { seq }
    \__cus_analysis_data_type_interactive:NN #1 \seq_show:N
  }
\cs_new:Npn \__cus_analysis_data_type_interactive:NN #1#2
  {
    \__cus_analysis_interactive:Nnn #1
      { Finding~\l__cus_analysis_cstype_tl }
      {
        { show } { #2 #1 }
      }
  }
\cs_new:Npn \__cus_analysis_control_sequence_else:Nnn #1#2#3
  {
    \tl_put_right:Nn \l__cus_analysis_result_tl { tl }
  }

\__cus_analysis_new:nn { 1 } % begin-group 
  {
    \tl_set:Nn \l__cus_analysis_result_tl
      { 
        charcode = 0x \__cus_char_to_unicode_o:N \l__cus_analysis_string_tl 
        \cus_analysis_sep:
        catcode  = \__cus_pad_tl:enn { \l__cus_analysis_catcode_tl } { 2 } { ~ }
        \cus_analysis_sep:
        \l__cus_analysis_meaning_tl 
      }
    \__cus_exp_args:ne {#1} { \__cus_analysis_indent: \l__cus_analysis_result_tl }
  }
\__cus_analysis_new_eq:nn { 2 } % end-group 
  { 1 }
\__cus_analysis_new_eq:nn { 3 } % math_toggle
  { 1 }
\__cus_analysis_new_eq:nn { 4 } % alignment
  { 1 }
\__cus_analysis_new_eq:nn { 6 } % parameter
  { 1 }
\__cus_analysis_new_eq:nn { 7 } % math_superscript
  { 1 }
\__cus_analysis_new_eq:nn { 8 } % math_subscript
  { 1 }
\__cus_analysis_new_eq:nn { 10 } % space
  { 1 }
\__cus_analysis_new_eq:nn { 11 } % letter 
  { 1 }
\__cus_analysis_new_eq:nn { 12 } % other 
  { 1 }
\__cus_analysis_new:nn { 13 } % active 
  {
    \tl_set:Nn \l__cus_analysis_result_tl
      {
        active~character~\l__cus_analysis_string_tl
        \cus_analysis_sep:
        charcode = 0x \__cus_char_to_unicode_o:N \l__cus_analysis_string_tl
        \cus_analysis_sep:
        catcode  = \__cus_pad_tl:enn { \l__cus_analysis_catcode_tl } { 2 } { ~ }
        \cus_analysis_sep:
      }
    \exp_after:wN \token_if_active:NTF #1
      {
        \tl_put_right:Nx \l__cus_analysis_result_tl
          {
            \str_if_eq:eeTF { \l__cus_analysis_string_tl } { undefined }
              { \l__cus_analysis_meaning_tl }
              { \l__cus_analysis_string_tl }%%%
          }
      }
      { \tl_put_right:Nn \l__cus_analysis_result_tl \l__cus_analysis_meaning_tl }
    \__cus_exp_args:ne {#1} { \__cus_analysis_indent: \l__cus_analysis_result_tl }
  }


\cs_new:Npn \__cus_pad_tl:nnn #1#2#3 % tl, len, with 
  { \prg_replicate:nn { #2 - \tl_count:n {#1} } {#3} #1 }
\cs_generate_variant:Nn \__cus_pad_tl:nnn { enn }
\cs_new:Npn \__cus_char_to_unicode:N #1 
  { \__cus_pad_tl:enn { \int_to_Hex:n { `#1 } } { 4 } { ~ } }
\cs_new:Npn \__cus_char_to_unicode_o:N #1 
  { \__cus_pad_tl:enn { \int_to_Hex:n { \exp_after:wN `#1 } } { 4 } { ~ } }
\cs_new:Npn \__cus_analysis_indent: { }
\cs_new:Npn \__cus_analysis_indent:n #1 { }

\cs_new_protected:Npn \__cus_analysis_interactive:Nnn #1#2#3
  {
    \bool_if:NT \l_cus_analysis_interactive_bool
      {
        \tl_set:Nx \l__cus_analysis_execute_list_tl { \__cus_tl_odd_items:n {#3} }
        \exp_args:Ne \ior_get_term:nN 
          {
            #2 ~ \l__cus_analysis_string_tl , ~action \iow_newline:
            \c_space_tl \c_space_tl 
            ( \cus_tl_use:Nn \l__cus_analysis_execute_list_tl {,} ,nonstop,execute)
          }
          \l__cus_analysis_input_tl
        \tl_trim_spaces:N \l__cus_analysis_input_tl
        \str_case_e:nnT { \l__cus_analysis_input_tl }
          {
            #3
            { nonstop } { \bool_set_false:N \l_cus_analysis_interactive_bool }
            { execute } { \__cus_analysis_execute_term:N #1 }
          }
          { } % { \__cus_analysis_interactive:Nnn #1 {#2} {#3} }
      }
  }


\endinput 

描述所有可能的记号：
control sequence：
  (
    control space 
    control symbol 
    control word
  )
  macro
    has no parameter
      quark 
      seq 
      prop 
      fp 
      LaTeX newcommand with option arg 
      LaTeX robust command
      LaTeX cmd command 
      LaTeX cmd environment 
      pure tl 
    has parameter
    --- outer 
  primitive 
    relax 
  register 
    count 
    dimen 
    skip 
    muskip 
    toks 
    marks 
    --- box 
    --- openin 
    --- openout 
  const integer 
    char 
    mathchar 
    Umathchar 
  font selection 
  undefined
  --- attribute 
  other internal tokens
character token：
  1: begin-group, group_begin
  2: end-group, group_end
  3: math shift, math_toggle 
  4: alignment tab, alignment
  6: macro parameter, parameter
  7: superscript, math_superscript
  8: subscript, math_subscript
  10: blank space, space
  11: the letter, letter 
  12: the character, other 
  13: active, active 
  --- 0 (escape), 5 (end_line), 9 (ignore), 14 (comment), and 15 (invalid)
active char：
  被let为一个 control sequence
  --- 被let为一个 active char 
  被let为一个普通字符
  undefined 